package com.mop.calc;
// $ANTLR 3.2 Sep 23, 2009 12:02:23 Translator.g 2010-05-11 17:50:58

import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;


import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;import java.util.Stack;
import java.util.List;
import java.util.ArrayList;

import org.antlr.stringtemplate.*;
import org.antlr.stringtemplate.language.*;
import java.util.HashMap;
public class Translator extends TreeParser {
    public static final String[] tokenNames = new String[] {
        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "ID", "EQ", "SEMI", "ECHO", "STR", "LOOP", "LPAREN", "RPAREN", "ENDLP", "COMP", "NUM", "ADD", "MUL", "SUB", "DIV", "WS"
    };
    public static final int ENDLP=12;
    public static final int SUB=17;
    public static final int COMP=13;
    public static final int ID=4;
    public static final int EOF=-1;
    public static final int SEMI=6;
    public static final int MUL=16;
    public static final int LPAREN=10;
    public static final int NUM=14;
    public static final int STR=8;
    public static final int RPAREN=11;
    public static final int ECHO=7;
    public static final int WS=19;
    public static final int LOOP=9;
    public static final int EQ=5;
    public static final int DIV=18;
    public static final int ADD=15;

    // delegates
    // delegators


        public Translator(TreeNodeStream input) {
            this(input, new RecognizerSharedState());
        }
        public Translator(TreeNodeStream input, RecognizerSharedState state) {
            super(input, state);
             
        }
        
    protected StringTemplateGroup templateLib =
      new StringTemplateGroup("TranslatorTemplates", AngleBracketTemplateLexer.class);

    public void setTemplateLib(StringTemplateGroup templateLib) {
      this.templateLib = templateLib;
    }
    public StringTemplateGroup getTemplateLib() {
      return templateLib;
    }
    /** allows convenient multi-value initialization:
     *  "new STAttrMap().put(...).put(...)"
     */
    public static class STAttrMap extends HashMap {
      public STAttrMap put(String attrName, Object value) {
        super.put(attrName, value);
        return this;
      }
      public STAttrMap put(String attrName, int value) {
        super.put(attrName, new Integer(value));
        return this;
      }
    }

    public String[] getTokenNames() { return Translator.tokenNames; }
    public String getGrammarFileName() { return "Translator.g"; }


    private int varSeq=1; //temporary variable sequence
    private List<String> reasons = new ArrayList<String>(0);

    public String getNewTempVar(){
    	return "_var" + "_" + varSeq++;
    }

    public void reportLogicError(int line,int column,String reason){
    	reasons.add("At line:" + line + " Column:" + column + " " + reason);
    }

    public List<String> getErrors(){
    	return reasons;
    }

    //variable
    private Map<String,Boolean> memory = new HashMap<String,Boolean>();



    protected static class root_scope {
        List<String> statementList;
    }
    protected Stack root_stack = new Stack();

    public static class root_return extends TreeRuleReturnScope {
        public StringTemplate st;
        public Object getTemplate() { return st; }
        public String toString() { return st==null?null:st.toString(); }
    };

    // $ANTLR start "root"
    // Translator.g:37:1: root : (a= statement )+ -> createUnit(statementList=$root::statementList);
    public final Translator.root_return root() throws RecognitionException {
        root_stack.push(new root_scope());
        Translator.root_return retval = new Translator.root_return();
        retval.start = input.LT(1);

        Translator.statement_return a = null;



        ((root_scope)root_stack.peek()).statementList = new ArrayList<String>();

        try {
            // Translator.g:44:2: ( (a= statement )+ -> createUnit(statementList=$root::statementList))
            // Translator.g:44:4: (a= statement )+
            {
            // Translator.g:44:4: (a= statement )+
            int cnt1=0;
            loop1:
            do {
                int alt1=2;
                int LA1_0 = input.LA(1);

                if ( (LA1_0==EQ||LA1_0==ECHO||LA1_0==LOOP) ) {
                    alt1=1;
                }


                switch (alt1) {
            	case 1 :
            	    // Translator.g:44:5: a= statement
            	    {
            	    pushFollow(FOLLOW_statement_in_root57);
            	    a=statement();

            	    state._fsp--;

            	    ((root_scope)root_stack.peek()).statementList.add((a!=null?a.st:null).toString());

            	    }
            	    break;

            	default :
            	    if ( cnt1 >= 1 ) break loop1;
                        EarlyExitException eee =
                            new EarlyExitException(1, input);
                        throw eee;
                }
                cnt1++;
            } while (true);



            // TEMPLATE REWRITE
            // 45:2: -> createUnit(statementList=$root::statementList)
            {
                retval.st = templateLib.getInstanceOf("createUnit",
              new STAttrMap().put("statementList", ((root_scope)root_stack.peek()).statementList));
            }


            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
            root_stack.pop();
        }
        return retval;
    }
    // $ANTLR end "root"

    protected static class statement_scope {
        List<String> statementList;
        boolean defined;
    }
    protected Stack statement_stack = new Stack();

    public static class statement_return extends TreeRuleReturnScope {
        public StringTemplate st;
        public Object getTemplate() { return st; }
        public String toString() { return st==null?null:st.toString(); }
    };

    // $ANTLR start "statement"
    // Translator.g:48:1: statement : ( ^( EQ ID expr ) -> createAssign(left=$ID.textrightvar=$expr.expr_varright=$expr.stdefined=$statement::defined) | ^( EQ ID atom ) -> createAssign(left=$ID.textrightvar=$atom.textdefined=$statement::defined) | ^( ECHO node ) -> createEcho(nodevar=$node.node_varnodecode=$node.st) | ^( ECHO STR ) -> createEcho(nodevar=$STR) | ^( LOOP a= ID b= node c= comp (d= statement )+ ) -> createLoop(repeatvar=$a.textreplacevar=$b.node_varreplacecode=$b.stcompcode=$c.stcompres=$c.comp_varblock=$statement::statementListdefined=$statement::defined));
    public final Translator.statement_return statement() throws RecognitionException {
        statement_stack.push(new statement_scope());
        Translator.statement_return retval = new Translator.statement_return();
        retval.start = input.LT(1);

        CommonTree a=null;
        CommonTree ID1=null;
        CommonTree ID3=null;
        CommonTree STR6=null;
        Translator.node_return b = null;

        Translator.comp_return c = null;

        Translator.statement_return d = null;

        Translator.expr_return expr2 = null;

        Translator.atom_return atom4 = null;

        Translator.node_return node5 = null;



        ((statement_scope)statement_stack.peek()).statementList = new ArrayList<String>();

        try {
            // Translator.g:56:2: ( ^( EQ ID expr ) -> createAssign(left=$ID.textrightvar=$expr.expr_varright=$expr.stdefined=$statement::defined) | ^( EQ ID atom ) -> createAssign(left=$ID.textrightvar=$atom.textdefined=$statement::defined) | ^( ECHO node ) -> createEcho(nodevar=$node.node_varnodecode=$node.st) | ^( ECHO STR ) -> createEcho(nodevar=$STR) | ^( LOOP a= ID b= node c= comp (d= statement )+ ) -> createLoop(repeatvar=$a.textreplacevar=$b.node_varreplacecode=$b.stcompcode=$c.stcompres=$c.comp_varblock=$statement::statementListdefined=$statement::defined))
            int alt3=5;
            alt3 = dfa3.predict(input);
            switch (alt3) {
                case 1 :
                    // Translator.g:56:4: ^( EQ ID expr )
                    {
                    match(input,EQ,FOLLOW_EQ_in_statement89); 

                    match(input, Token.DOWN, null); 
                    ID1=(CommonTree)match(input,ID,FOLLOW_ID_in_statement91); 
                    pushFollow(FOLLOW_expr_in_statement93);
                    expr2=expr();

                    state._fsp--;


                    match(input, Token.UP, null); 

                    		((statement_scope)statement_stack.peek()).defined = memory.get((ID1!=null?ID1.getText():null)) != null?memory.get((ID1!=null?ID1.getText():null)):Boolean.FALSE;
                    		memory.put((ID1!=null?ID1.getText():null),Boolean.TRUE);
                    	


                    // TEMPLATE REWRITE
                    // 61:2: -> createAssign(left=$ID.textrightvar=$expr.expr_varright=$expr.stdefined=$statement::defined)
                    {
                        retval.st = templateLib.getInstanceOf("createAssign",
                      new STAttrMap().put("left", (ID1!=null?ID1.getText():null)).put("rightvar", (expr2!=null?expr2.expr_var:null)).put("right", (expr2!=null?expr2.st:null)).put("defined", ((statement_scope)statement_stack.peek()).defined));
                    }


                    }
                    break;
                case 2 :
                    // Translator.g:62:4: ^( EQ ID atom )
                    {
                    match(input,EQ,FOLLOW_EQ_in_statement126); 

                    match(input, Token.DOWN, null); 
                    ID3=(CommonTree)match(input,ID,FOLLOW_ID_in_statement128); 
                    pushFollow(FOLLOW_atom_in_statement130);
                    atom4=atom();

                    state._fsp--;


                    match(input, Token.UP, null); 

                    		((statement_scope)statement_stack.peek()).defined = memory.get((ID3!=null?ID3.getText():null)) != null?memory.get((ID3!=null?ID3.getText():null)):Boolean.FALSE;
                    		memory.put((ID3!=null?ID3.getText():null),Boolean.TRUE);
                    	


                    // TEMPLATE REWRITE
                    // 67:2: -> createAssign(left=$ID.textrightvar=$atom.textdefined=$statement::defined)
                    {
                        retval.st = templateLib.getInstanceOf("createAssign",
                      new STAttrMap().put("left", (ID3!=null?ID3.getText():null)).put("rightvar", (atom4!=null?(input.getTokenStream().toString(
                      input.getTreeAdaptor().getTokenStartIndex(atom4.start),
                      input.getTreeAdaptor().getTokenStopIndex(atom4.start))):null)).put("defined", ((statement_scope)statement_stack.peek()).defined));
                    }


                    }
                    break;
                case 3 :
                    // Translator.g:68:4: ^( ECHO node )
                    {
                    match(input,ECHO,FOLLOW_ECHO_in_statement158); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_node_in_statement160);
                    node5=node();

                    state._fsp--;


                    match(input, Token.UP, null); 


                    // TEMPLATE REWRITE
                    // 69:2: -> createEcho(nodevar=$node.node_varnodecode=$node.st)
                    {
                        retval.st = templateLib.getInstanceOf("createEcho",
                      new STAttrMap().put("nodevar", (node5!=null?node5.node_var:null)).put("nodecode", (node5!=null?node5.st:null)));
                    }


                    }
                    break;
                case 4 :
                    // Translator.g:70:4: ^( ECHO STR )
                    {
                    match(input,ECHO,FOLLOW_ECHO_in_statement181); 

                    match(input, Token.DOWN, null); 
                    STR6=(CommonTree)match(input,STR,FOLLOW_STR_in_statement183); 

                    match(input, Token.UP, null); 


                    // TEMPLATE REWRITE
                    // 71:2: -> createEcho(nodevar=$STR)
                    {
                        retval.st = templateLib.getInstanceOf("createEcho",
                      new STAttrMap().put("nodevar", STR6));
                    }


                    }
                    break;
                case 5 :
                    // Translator.g:72:4: ^( LOOP a= ID b= node c= comp (d= statement )+ )
                    {
                    match(input,LOOP,FOLLOW_LOOP_in_statement200); 

                    match(input, Token.DOWN, null); 
                    a=(CommonTree)match(input,ID,FOLLOW_ID_in_statement204); 
                    pushFollow(FOLLOW_node_in_statement208);
                    b=node();

                    state._fsp--;

                    pushFollow(FOLLOW_comp_in_statement212);
                    c=comp();

                    state._fsp--;

                    // Translator.g:72:30: (d= statement )+
                    int cnt2=0;
                    loop2:
                    do {
                        int alt2=2;
                        int LA2_0 = input.LA(1);

                        if ( (LA2_0==EQ||LA2_0==ECHO||LA2_0==LOOP) ) {
                            alt2=1;
                        }


                        switch (alt2) {
                    	case 1 :
                    	    // Translator.g:72:31: d= statement
                    	    {
                    	    pushFollow(FOLLOW_statement_in_statement217);
                    	    d=statement();

                    	    state._fsp--;

                    	    ((statement_scope)statement_stack.peek()).statementList.add((d!=null?d.st:null).toString());

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt2 >= 1 ) break loop2;
                                EarlyExitException eee =
                                    new EarlyExitException(2, input);
                                throw eee;
                        }
                        cnt2++;
                    } while (true);


                    match(input, Token.UP, null); 

                    		((statement_scope)statement_stack.peek()).defined = memory.get((a!=null?a.getText():null)) != null?memory.get((a!=null?a.getText():null)):Boolean.FALSE;
                    	


                    // TEMPLATE REWRITE
                    // 76:2: -> createLoop(repeatvar=$a.textreplacevar=$b.node_varreplacecode=$b.stcompcode=$c.stcompres=$c.comp_varblock=$statement::statementListdefined=$statement::defined)
                    {
                        retval.st = templateLib.getInstanceOf("createLoop",
                      new STAttrMap().put("repeatvar", (a!=null?a.getText():null)).put("replacevar", (b!=null?b.node_var:null)).put("replacecode", (b!=null?b.st:null)).put("compcode", (c!=null?c.st:null)).put("compres", (c!=null?c.comp_var:null)).put("block", ((statement_scope)statement_stack.peek()).statementList).put("defined", ((statement_scope)statement_stack.peek()).defined));
                    }


                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
            statement_stack.pop();
        }
        return retval;
    }
    // $ANTLR end "statement"

    protected static class expr_scope {
        List node_vars;
        List node_codes;
    }
    protected Stack expr_stack = new Stack();

    public static class expr_return extends TreeRuleReturnScope {
        public String expr_var;
        public StringTemplate st;
        public Object getTemplate() { return st; }
        public String toString() { return st==null?null:st.toString(); }
    };

    // $ANTLR start "expr"
    // Translator.g:79:1: expr returns [String expr_var] : ( ^( ADD ( node )+ ) -> createAdd(var=$expr_varitemVars=$expr::node_varsaddItems=$expr::node_codes) | ^( MUL ( node )+ ) -> createMul(var=$expr_varitemVars=$expr::node_varsmulItems=$expr::node_codes) | ^( SUB ( node )+ ) -> createSub(var=$expr_varitemVars=$expr::node_varssubItems=$expr::node_codes) | ^( DIV ( node )+ ) -> createDiv(var=$expr_varitemVars=$expr::node_varsdivItems=$expr::node_codes));
    public final Translator.expr_return expr() throws RecognitionException {
        expr_stack.push(new expr_scope());
        Translator.expr_return retval = new Translator.expr_return();
        retval.start = input.LT(1);

        CommonTree SUB10=null;
        CommonTree DIV12=null;
        Translator.node_return node7 = null;

        Translator.node_return node8 = null;

        Translator.node_return node9 = null;

        Translator.node_return node11 = null;



        retval.expr_var = getNewTempVar();
        ((expr_scope)expr_stack.peek()).node_vars = new ArrayList();
        ((expr_scope)expr_stack.peek()).node_codes = new ArrayList();

        try {
            // Translator.g:89:2: ( ^( ADD ( node )+ ) -> createAdd(var=$expr_varitemVars=$expr::node_varsaddItems=$expr::node_codes) | ^( MUL ( node )+ ) -> createMul(var=$expr_varitemVars=$expr::node_varsmulItems=$expr::node_codes) | ^( SUB ( node )+ ) -> createSub(var=$expr_varitemVars=$expr::node_varssubItems=$expr::node_codes) | ^( DIV ( node )+ ) -> createDiv(var=$expr_varitemVars=$expr::node_varsdivItems=$expr::node_codes))
            int alt8=4;
            switch ( input.LA(1) ) {
            case ADD:
                {
                alt8=1;
                }
                break;
            case MUL:
                {
                alt8=2;
                }
                break;
            case SUB:
                {
                alt8=3;
                }
                break;
            case DIV:
                {
                alt8=4;
                }
                break;
            default:
                NoViableAltException nvae =
                    new NoViableAltException("", 8, 0, input);

                throw nvae;
            }

            switch (alt8) {
                case 1 :
                    // Translator.g:89:4: ^( ADD ( node )+ )
                    {
                    match(input,ADD,FOLLOW_ADD_in_expr281); 

                    match(input, Token.DOWN, null); 
                    // Translator.g:89:10: ( node )+
                    int cnt4=0;
                    loop4:
                    do {
                        int alt4=2;
                        int LA4_0 = input.LA(1);

                        if ( (LA4_0==ID||(LA4_0>=NUM && LA4_0<=DIV)) ) {
                            alt4=1;
                        }


                        switch (alt4) {
                    	case 1 :
                    	    // Translator.g:89:11: node
                    	    {
                    	    pushFollow(FOLLOW_node_in_expr284);
                    	    node7=node();

                    	    state._fsp--;

                    	    ((expr_scope)expr_stack.peek()).node_vars.add((node7!=null?node7.node_var:null));((expr_scope)expr_stack.peek()).node_codes.add((node7!=null?node7.st:null));

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt4 >= 1 ) break loop4;
                                EarlyExitException eee =
                                    new EarlyExitException(4, input);
                                throw eee;
                        }
                        cnt4++;
                    } while (true);


                    match(input, Token.UP, null); 


                    // TEMPLATE REWRITE
                    // 90:2: -> createAdd(var=$expr_varitemVars=$expr::node_varsaddItems=$expr::node_codes)
                    {
                        retval.st = templateLib.getInstanceOf("createAdd",
                      new STAttrMap().put("var", retval.expr_var).put("itemVars", ((expr_scope)expr_stack.peek()).node_vars).put("addItems", ((expr_scope)expr_stack.peek()).node_codes));
                    }


                    }
                    break;
                case 2 :
                    // Translator.g:91:4: ^( MUL ( node )+ )
                    {
                    match(input,MUL,FOLLOW_MUL_in_expr314); 

                    match(input, Token.DOWN, null); 
                    // Translator.g:91:10: ( node )+
                    int cnt5=0;
                    loop5:
                    do {
                        int alt5=2;
                        int LA5_0 = input.LA(1);

                        if ( (LA5_0==ID||(LA5_0>=NUM && LA5_0<=DIV)) ) {
                            alt5=1;
                        }


                        switch (alt5) {
                    	case 1 :
                    	    // Translator.g:91:11: node
                    	    {
                    	    pushFollow(FOLLOW_node_in_expr317);
                    	    node8=node();

                    	    state._fsp--;

                    	    ((expr_scope)expr_stack.peek()).node_vars.add((node8!=null?node8.node_var:null));((expr_scope)expr_stack.peek()).node_codes.add((node8!=null?node8.st:null));

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt5 >= 1 ) break loop5;
                                EarlyExitException eee =
                                    new EarlyExitException(5, input);
                                throw eee;
                        }
                        cnt5++;
                    } while (true);


                    match(input, Token.UP, null); 


                    // TEMPLATE REWRITE
                    // 92:2: -> createMul(var=$expr_varitemVars=$expr::node_varsmulItems=$expr::node_codes)
                    {
                        retval.st = templateLib.getInstanceOf("createMul",
                      new STAttrMap().put("var", retval.expr_var).put("itemVars", ((expr_scope)expr_stack.peek()).node_vars).put("mulItems", ((expr_scope)expr_stack.peek()).node_codes));
                    }


                    }
                    break;
                case 3 :
                    // Translator.g:93:4: ^( SUB ( node )+ )
                    {
                    SUB10=(CommonTree)match(input,SUB,FOLLOW_SUB_in_expr345); 

                    match(input, Token.DOWN, null); 
                    // Translator.g:93:10: ( node )+
                    int cnt6=0;
                    loop6:
                    do {
                        int alt6=2;
                        int LA6_0 = input.LA(1);

                        if ( (LA6_0==ID||(LA6_0>=NUM && LA6_0<=DIV)) ) {
                            alt6=1;
                        }


                        switch (alt6) {
                    	case 1 :
                    	    // Translator.g:93:11: node
                    	    {
                    	    pushFollow(FOLLOW_node_in_expr348);
                    	    node9=node();

                    	    state._fsp--;

                    	    ((expr_scope)expr_stack.peek()).node_vars.add((node9!=null?node9.node_var:null));((expr_scope)expr_stack.peek()).node_codes.add((node9!=null?node9.st:null));

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt6 >= 1 ) break loop6;
                                EarlyExitException eee =
                                    new EarlyExitException(6, input);
                                throw eee;
                        }
                        cnt6++;
                    } while (true);


                    match(input, Token.UP, null); 

                    		if(((expr_scope)expr_stack.peek()).node_vars.size() > 2){
                    			reportLogicError(SUB10.token.getLine(), SUB10.token.getCharPositionInLine() , "Substract operation only two nodes allowd!"); 
                    		}
                    	


                    // TEMPLATE REWRITE
                    // 99:2: -> createSub(var=$expr_varitemVars=$expr::node_varssubItems=$expr::node_codes)
                    {
                        retval.st = templateLib.getInstanceOf("createSub",
                      new STAttrMap().put("var", retval.expr_var).put("itemVars", ((expr_scope)expr_stack.peek()).node_vars).put("subItems", ((expr_scope)expr_stack.peek()).node_codes));
                    }


                    }
                    break;
                case 4 :
                    // Translator.g:100:4: ^( DIV ( node )+ )
                    {
                    DIV12=(CommonTree)match(input,DIV,FOLLOW_DIV_in_expr379); 

                    match(input, Token.DOWN, null); 
                    // Translator.g:100:10: ( node )+
                    int cnt7=0;
                    loop7:
                    do {
                        int alt7=2;
                        int LA7_0 = input.LA(1);

                        if ( (LA7_0==ID||(LA7_0>=NUM && LA7_0<=DIV)) ) {
                            alt7=1;
                        }


                        switch (alt7) {
                    	case 1 :
                    	    // Translator.g:100:11: node
                    	    {
                    	    pushFollow(FOLLOW_node_in_expr382);
                    	    node11=node();

                    	    state._fsp--;

                    	    ((expr_scope)expr_stack.peek()).node_vars.add((node11!=null?node11.node_var:null));((expr_scope)expr_stack.peek()).node_codes.add((node11!=null?node11.st:null));

                    	    }
                    	    break;

                    	default :
                    	    if ( cnt7 >= 1 ) break loop7;
                                EarlyExitException eee =
                                    new EarlyExitException(7, input);
                                throw eee;
                        }
                        cnt7++;
                    } while (true);


                    match(input, Token.UP, null); 

                    		if(((expr_scope)expr_stack.peek()).node_vars.size() > 2){
                    			reportLogicError(DIV12.token.getLine(), DIV12.token.getCharPositionInLine() , "Divide operation only two nodes allowd!"); 
                    		}
                    	


                    // TEMPLATE REWRITE
                    // 106:2: -> createDiv(var=$expr_varitemVars=$expr::node_varsdivItems=$expr::node_codes)
                    {
                        retval.st = templateLib.getInstanceOf("createDiv",
                      new STAttrMap().put("var", retval.expr_var).put("itemVars", ((expr_scope)expr_stack.peek()).node_vars).put("divItems", ((expr_scope)expr_stack.peek()).node_codes));
                    }


                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
            expr_stack.pop();
        }
        return retval;
    }
    // $ANTLR end "expr"

    public static class comp_return extends TreeRuleReturnScope {
        public String comp_var;
        public StringTemplate st;
        public Object getTemplate() { return st; }
        public String toString() { return st==null?null:st.toString(); }
    };

    // $ANTLR start "comp"
    // Translator.g:108:1: comp returns [String comp_var] : ^(a= COMP b= node c= node ) -> createComp(compres=$comp_varoper=$a.textleftvar=$b.node_varleftcode=$b.strightvar=$c.node_varrightcode=$c.st);
    public final Translator.comp_return comp() throws RecognitionException {
        Translator.comp_return retval = new Translator.comp_return();
        retval.start = input.LT(1);

        CommonTree a=null;
        Translator.node_return b = null;

        Translator.node_return c = null;



        retval.comp_var = getNewTempVar();

        try {
            // Translator.g:112:2: ( ^(a= COMP b= node c= node ) -> createComp(compres=$comp_varoper=$a.textleftvar=$b.node_varleftcode=$b.strightvar=$c.node_varrightcode=$c.st))
            // Translator.g:112:4: ^(a= COMP b= node c= node )
            {
            a=(CommonTree)match(input,COMP,FOLLOW_COMP_in_comp431); 

            match(input, Token.DOWN, null); 
            pushFollow(FOLLOW_node_in_comp435);
            b=node();

            state._fsp--;

            pushFollow(FOLLOW_node_in_comp439);
            c=node();

            state._fsp--;


            match(input, Token.UP, null); 


            // TEMPLATE REWRITE
            // 113:2: -> createComp(compres=$comp_varoper=$a.textleftvar=$b.node_varleftcode=$b.strightvar=$c.node_varrightcode=$c.st)
            {
                retval.st = templateLib.getInstanceOf("createComp",
              new STAttrMap().put("compres", retval.comp_var).put("oper", (a!=null?a.getText():null)).put("leftvar", (b!=null?b.node_var:null)).put("leftcode", (b!=null?b.st:null)).put("rightvar", (c!=null?c.node_var:null)).put("rightcode", (c!=null?c.st:null)));
            }


            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "comp"

    public static class node_return extends TreeRuleReturnScope {
        public String node_var;
        public StringTemplate st;
        public Object getTemplate() { return st; }
        public String toString() { return st==null?null:st.toString(); }
    };

    // $ANTLR start "node"
    // Translator.g:115:1: node returns [String node_var] : ( expr -> createExpr(left=$node_varrightvar=$expr.expr_varright=$expr.st) | atom -> createAtom(left=$node_varright=$atom.text));
    public final Translator.node_return node() throws RecognitionException {
        Translator.node_return retval = new Translator.node_return();
        retval.start = input.LT(1);

        Translator.expr_return expr13 = null;

        Translator.atom_return atom14 = null;



        retval.node_var = getNewTempVar(); 

        try {
            // Translator.g:119:2: ( expr -> createExpr(left=$node_varrightvar=$expr.expr_varright=$expr.st) | atom -> createAtom(left=$node_varright=$atom.text))
            int alt9=2;
            int LA9_0 = input.LA(1);

            if ( ((LA9_0>=ADD && LA9_0<=DIV)) ) {
                alt9=1;
            }
            else if ( (LA9_0==ID||LA9_0==NUM) ) {
                alt9=2;
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 9, 0, input);

                throw nvae;
            }
            switch (alt9) {
                case 1 :
                    // Translator.g:119:4: expr
                    {
                    pushFollow(FOLLOW_expr_in_node490);
                    expr13=expr();

                    state._fsp--;



                    // TEMPLATE REWRITE
                    // 120:2: -> createExpr(left=$node_varrightvar=$expr.expr_varright=$expr.st)
                    {
                        retval.st = templateLib.getInstanceOf("createExpr",
                      new STAttrMap().put("left", retval.node_var).put("rightvar", (expr13!=null?expr13.expr_var:null)).put("right", (expr13!=null?expr13.st:null)));
                    }


                    }
                    break;
                case 2 :
                    // Translator.g:121:4: atom
                    {
                    pushFollow(FOLLOW_atom_in_node514);
                    atom14=atom();

                    state._fsp--;



                    // TEMPLATE REWRITE
                    // 122:2: -> createAtom(left=$node_varright=$atom.text)
                    {
                        retval.st = templateLib.getInstanceOf("createAtom",
                      new STAttrMap().put("left", retval.node_var).put("right", (atom14!=null?(input.getTokenStream().toString(
                      input.getTreeAdaptor().getTokenStartIndex(atom14.start),
                      input.getTreeAdaptor().getTokenStopIndex(atom14.start))):null)));
                    }


                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "node"

    public static class atom_return extends TreeRuleReturnScope {
        public StringTemplate st;
        public Object getTemplate() { return st; }
        public String toString() { return st==null?null:st.toString(); }
    };

    // $ANTLR start "atom"
    // Translator.g:125:1: atom : ( NUM -> createNumber(text=$NUM.text) | ID -> createID(text=$ID.text));
    public final Translator.atom_return atom() throws RecognitionException {
        Translator.atom_return retval = new Translator.atom_return();
        retval.start = input.LT(1);

        CommonTree NUM15=null;
        CommonTree ID16=null;

        try {
            // Translator.g:126:2: ( NUM -> createNumber(text=$NUM.text) | ID -> createID(text=$ID.text))
            int alt10=2;
            int LA10_0 = input.LA(1);

            if ( (LA10_0==NUM) ) {
                alt10=1;
            }
            else if ( (LA10_0==ID) ) {
                alt10=2;
            }
            else {
                NoViableAltException nvae =
                    new NoViableAltException("", 10, 0, input);

                throw nvae;
            }
            switch (alt10) {
                case 1 :
                    // Translator.g:126:4: NUM
                    {
                    NUM15=(CommonTree)match(input,NUM,FOLLOW_NUM_in_atom544); 

                    		try{
                    			Integer.parseInt((NUM15!=null?NUM15.getText():null));
                    		}catch(NumberFormatException e){
                    			reportLogicError(NUM15.token.getLine(), NUM15.token.getCharPositionInLine() , "Illegal Number Format!");
                    		}
                    	


                    // TEMPLATE REWRITE
                    // 134:2: -> createNumber(text=$NUM.text)
                    {
                        retval.st = templateLib.getInstanceOf("createNumber",
                      new STAttrMap().put("text", (NUM15!=null?NUM15.getText():null)));
                    }


                    }
                    break;
                case 2 :
                    // Translator.g:135:5: ID
                    {
                    ID16=(CommonTree)match(input,ID,FOLLOW_ID_in_atom566); 

                    		if(memory.get((ID16!=null?ID16.getText():null)) == null){
                    			reportLogicError(ID16.token.getLine(), ID16.token.getCharPositionInLine() , (ID16!=null?ID16.getText():null) + " Identifier Undefined!");
                    		}
                    	


                    // TEMPLATE REWRITE
                    // 141:2: -> createID(text=$ID.text)
                    {
                        retval.st = templateLib.getInstanceOf("createID",
                      new STAttrMap().put("text", (ID16!=null?ID16.getText():null)));
                    }


                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "atom"

    // Delegated rules


    protected DFA3 dfa3 = new DFA3(this);
    static final String DFA3_eotS =
        "\13\uffff";
    static final String DFA3_eofS =
        "\13\uffff";
    static final String DFA3_minS =
        "\1\5\2\2\1\uffff\3\4\4\uffff";
    static final String DFA3_maxS =
        "\1\11\2\2\1\uffff\1\4\2\22\4\uffff";
    static final String DFA3_acceptS =
        "\3\uffff\1\5\3\uffff\1\4\1\3\1\2\1\1";
    static final String DFA3_specialS =
        "\13\uffff}>";
    static final String[] DFA3_transitionS = {
            "\1\1\1\uffff\1\2\1\uffff\1\3",
            "\1\4",
            "\1\5",
            "",
            "\1\6",
            "\1\10\3\uffff\1\7\5\uffff\5\10",
            "\1\11\11\uffff\1\11\4\12",
            "",
            "",
            "",
            ""
    };

    static final short[] DFA3_eot = DFA.unpackEncodedString(DFA3_eotS);
    static final short[] DFA3_eof = DFA.unpackEncodedString(DFA3_eofS);
    static final char[] DFA3_min = DFA.unpackEncodedStringToUnsignedChars(DFA3_minS);
    static final char[] DFA3_max = DFA.unpackEncodedStringToUnsignedChars(DFA3_maxS);
    static final short[] DFA3_accept = DFA.unpackEncodedString(DFA3_acceptS);
    static final short[] DFA3_special = DFA.unpackEncodedString(DFA3_specialS);
    static final short[][] DFA3_transition;

    static {
        int numStates = DFA3_transitionS.length;
        DFA3_transition = new short[numStates][];
        for (int i=0; i<numStates; i++) {
            DFA3_transition[i] = DFA.unpackEncodedString(DFA3_transitionS[i]);
        }
    }

    class DFA3 extends DFA {

        public DFA3(BaseRecognizer recognizer) {
            this.recognizer = recognizer;
            this.decisionNumber = 3;
            this.eot = DFA3_eot;
            this.eof = DFA3_eof;
            this.min = DFA3_min;
            this.max = DFA3_max;
            this.accept = DFA3_accept;
            this.special = DFA3_special;
            this.transition = DFA3_transition;
        }
        public String getDescription() {
            return "48:1: statement : ( ^( EQ ID expr ) -> createAssign(left=$ID.textrightvar=$expr.expr_varright=$expr.stdefined=$statement::defined) | ^( EQ ID atom ) -> createAssign(left=$ID.textrightvar=$atom.textdefined=$statement::defined) | ^( ECHO node ) -> createEcho(nodevar=$node.node_varnodecode=$node.st) | ^( ECHO STR ) -> createEcho(nodevar=$STR) | ^( LOOP a= ID b= node c= comp (d= statement )+ ) -> createLoop(repeatvar=$a.textreplacevar=$b.node_varreplacecode=$b.stcompcode=$c.stcompres=$c.comp_varblock=$statement::statementListdefined=$statement::defined));";
        }
    }
 

    public static final BitSet FOLLOW_statement_in_root57 = new BitSet(new long[]{0x00000000000002A2L});
    public static final BitSet FOLLOW_EQ_in_statement89 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_ID_in_statement91 = new BitSet(new long[]{0x0000000000078000L});
    public static final BitSet FOLLOW_expr_in_statement93 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_EQ_in_statement126 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_ID_in_statement128 = new BitSet(new long[]{0x0000000000004010L});
    public static final BitSet FOLLOW_atom_in_statement130 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_ECHO_in_statement158 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_node_in_statement160 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_ECHO_in_statement181 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_STR_in_statement183 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_LOOP_in_statement200 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_ID_in_statement204 = new BitSet(new long[]{0x000000000007C010L});
    public static final BitSet FOLLOW_node_in_statement208 = new BitSet(new long[]{0x0000000000002000L});
    public static final BitSet FOLLOW_comp_in_statement212 = new BitSet(new long[]{0x00000000000002A8L});
    public static final BitSet FOLLOW_statement_in_statement217 = new BitSet(new long[]{0x00000000000002A8L});
    public static final BitSet FOLLOW_ADD_in_expr281 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_node_in_expr284 = new BitSet(new long[]{0x000000000007C018L});
    public static final BitSet FOLLOW_MUL_in_expr314 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_node_in_expr317 = new BitSet(new long[]{0x000000000007C018L});
    public static final BitSet FOLLOW_SUB_in_expr345 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_node_in_expr348 = new BitSet(new long[]{0x000000000007C018L});
    public static final BitSet FOLLOW_DIV_in_expr379 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_node_in_expr382 = new BitSet(new long[]{0x000000000007C018L});
    public static final BitSet FOLLOW_COMP_in_comp431 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_node_in_comp435 = new BitSet(new long[]{0x000000000007C010L});
    public static final BitSet FOLLOW_node_in_comp439 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_expr_in_node490 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_atom_in_node514 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_NUM_in_atom544 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ID_in_atom566 = new BitSet(new long[]{0x0000000000000002L});

}